

#ifndef __I_EVENT_RECEIVER_H_INCLUDED__
#define __I_EVENT_RECEIVER_H_INCLUDED__

#include "ILogger.h"
#include "position2d.h"
#include "Keycodes.h"

namespace irr
{
    //! Enumeration for all event types there are.
    enum EEVENT_TYPE
    {
        //! An event of the graphical user interface.
        EET_GUI_EVENT = 0,

        //! A mouse input event.
        EET_MOUSE_INPUT_EVENT,

        //! A key input evant.
        EET_KEY_INPUT_EVENT,

        //! A log event
        EET_LOG_TEXT_EVENT,

        //! An audio event
        EET_AUDIO_EVENT,

        //! A user event with user data. This is not used by engine and can be used
        //! to send user specific data though the system.
        EET_USER_EVENT
    };

    /* not used yet
    enum EAUDIO_EVENT
    {

    EAE_PLAY_BEGIN = 0,

    EAE_PLAYING,

    EAE_STOP,

    EAE_ERROR

    }; */

    //! Enumeration for all mouse input events
    enum EMOUSE_INPUT_EVENT
    {
        //! Left mouse button was pressed down.
        EMIE_LMOUSE_PRESSED_DOWN = 0,

        //! Right mouse button was pressed down.
        EMIE_RMOUSE_PRESSED_DOWN,

        //! Middle mouse button was pressed down.
        EMIE_MMOUSE_PRESSED_DOWN,

        //! Left mouse button was left up.
        EMIE_LMOUSE_LEFT_UP,

        //! Right mouse button was left up.
        EMIE_RMOUSE_LEFT_UP,

        //! Middle mouse button was left up.
        EMIE_MMOUSE_LEFT_UP,

        //! The mouse cursor changed its position.
        EMIE_MOUSE_MOVED,

        //! The mouse wheel was moved. Use Wheel value in event data to find out 
        //! in what direction and how fast.
        EMIE_MOUSE_WHEEL, 
    };

    namespace gui
    {

        class IGUIElement;

        //! Enumeration for all events which are sendable by the gui system
        enum EGUI_EVENT_TYPE
        {
            //! A gui element has lost its focus.
            EGET_ELEMENT_FOCUS_LOST = 0,

            //! A gui element was hovered.
            EGET_ELEMENT_HOVERED,

            //! A hovered gui element was left
            EGET_ELEMENT_LEFT,

            //! A button was clicked.
            EGET_BUTTON_CLICKED,

            //! A scrollbar has changed its position.
            EGET_SCROLL_BAR_CHANGED,

            //! A checkbox has changed its check state.
            EGET_CHECKBOX_CHANGED,

            //! A new item in a listbox was seleted.
            EGET_LISTBOX_CHANGED, 

            //! An item in the listbox was selected, which was already selected.
            EGET_LISTBOX_SELECTED_AGAIN, 

            //! A file has been selected in the file open dialog
            EGET_FILE_SELECTED,

            //! A file open dialog has been closed without choosing a file
            EGET_FILE_CHOOSE_DIALOG_CANCELLED,

            //! 'Yes' was clicked on a messagebox
            EGET_MESSAGEBOX_YES,

            //! 'No' was clicked on a messagebox
            EGET_MESSAGEBOX_NO,

            //! 'OK' was clicked on a messagebox
            EGET_MESSAGEBOX_OK,

            //! 'Cancel' was clicked on a messagebox
            EGET_MESSAGEBOX_CANCEL,

            //! In an editbox was pressed 'ENTER'
            EGET_EDITBOX_ENTER,

            //! The tab was changed in an tab control
            EGET_TAB_CHANGED,

            //! A menu item was selected in a (context) menu
            EGET_MENU_ITEM_SELECTED,

            //! The selection in a combo box has been changed
            EGET_COMBO_BOX_CHANGED
        };
    } // end namespace gui


    //! Struct for holding event data. An event can be a gui, mouse or keyboard event.
    struct SEvent
    {
        EEVENT_TYPE EventType;

        union
        {
            struct 
            {
                //! IGUIElement who called the event
                gui::IGUIElement* Caller;

                //! Type of GUI Event
                gui::EGUI_EVENT_TYPE EventType;			

            } GUIEvent;

            struct
            {
                //! X position of mouse cursor
                s32 X;

                //! Y position of mouse cursor
                s32 Y;

                //! mouse wheel delta, usually 1.0 or -1.0.
                /** Only valid if event was EMIE_MOUSE_WHEEL */
                f32 Wheel; 

                //! type of mouse event
                EMOUSE_INPUT_EVENT Event;
            } MouseInput;

            struct
            {
                //! Character corresponding to the key (0, if not a character)
                wchar_t Char; 

                //! Key which has been pressed or released
                EKEY_CODE Key; 

                //! if not pressed, then the key was left up
                bool PressedDown; 

                //! the first time that the button is pressed
                bool PressedOnce;

                //! true if shift was also pressed
                bool Shift; 

                //! true if ctrl was also pressed
                bool Control; 
            } KeyInput;

            struct
            {
                //! pointer to text which has been logged
                const c8* Text;

                //! log level in which the text has been logged
                ELOG_LEVEL Level;
            } LogEvent;

            struct
            {
                //! Some user specified data as int
                s32 UserData1; 

                //! Another user specified data as int
                s32 UserData2; 

                //! Some user specified data as float
                f32 UserData3; 
            } UserEvent;

            /* struct
            {
            int audioId;
            EAUDIO_EVENT evt;

            } AudioEvent; */

        };

    };

    //! Interface of an object wich can receive events.
    class IEventReceiver
    {
    public:

        virtual ~IEventReceiver() {};

        //! called if an event happened. returns true if event was processed
        virtual bool OnEvent(SEvent event) = 0;
    };


} // end namespace

#endif


